library('grid')

# To start:
# 1. Start Java Midi recorder
# 2. Submit code below
# 3. Strike a key

STATUS_UP <- 128
STATUS_DOWN <- 144
PLOT_DELAY_MSECS <- 0.500
TIME_SERIES_WINDOW_SIZE <- 30
TIME_SERIES_FILTER_SIZE <- 6
TIME_SERIES_TIME_AXIS <- FALSE # If TRUE, series plotted with real time on X axis, otherwise X is event index

run <- function() {
	c <- socketConnection(port=8888,blocking=T)
	i <- 1
	down_count <- 0
	up_count <- 0
	exit <- FALSE
	graphics.off()
	quartz()
	par(mfrow=c(2,1))
	quartz()
	par(mfrow=c(4,1))
	fnames <- c("time","tickCount","note","status","pressure")
	db <- list(
			history=list(
					pressure=list(),
					pressure_seq=c(),
					duration=list(),
					duration_seq=list(),
					start_tick=0
			),
			status=list(
					pressure=rep(0,128),
					duration=rep(0,128),
					last_press_time=rep(0,128),
					hit_count=rep(0,128)
			)
	)
	
	last_plot_time <- proc.time()['elapsed']
	while (!exit) {
		line <- unlist(strsplit(readLines(c,n=1)," "))
		event <- as.integer(line)
		names(event) <- fnames
		if (i==1) {
			#*** Initialize key log on first event
			keylog <- data.frame(matrix(event,nrow=1))
			colnames(keylog) <- fnames
		} else {
			keylog <- rbind(keylog,event)
		}
		if (event['status'] == STATUS_UP) {
			up_count <- up_count + 1
			duration <- (event['time'] - db$status$last_press_time[event['note']])/1000
			#if (db$history$duration_seq
			if (length(db$history$duration)==0) {
				db$history$duration[[event['note']]] <- duration
			} else {
				db$history$duration[[event['note']]] <- c(db$history$duration[[event['note']]],duration)
			}
			db$status$pressure[event['note']] <- 0
		} else {
			db$status$duration[event['note']] <- 0
			pressure <- event['pressure']
			db$status$pressure[event['note']] <- pressure 
			db$status$last_press_time[event['note']] <- event['time']
			if (length(db$history$pressure)==0) {
				db$history$pressure[[event['note']]] <- pressure
			} else {
				db$history$pressure[[event['note']]] <- c(db$history$pressure[[event['note']]],pressure)
			}
			sprintf("note=%i;i=%i",event['note'],i)
			if (event['note']==21) { #*** Exit if lowest key pressed
				exit <- TRUE
			}	
			down_events <- keylog[keylog$status == STATUS_DOWN,]
			if (nrow(down_events) >= TIME_SERIES_WINDOW_SIZE) {
				wstart <- nrow(down_events) - TIME_SERIES_WINDOW_SIZE + 1
			} else {
				wstart <- 1
			}
			wend <- nrow(down_events)
			down_events <- down_events[wstart:wend,]
			if (i >= TIME_SERIES_FILTER_SIZE) {
				pressure_history <- cbind(down_events$pressure,filter(down_events$pressure,filter=rep(1/TIME_SERIES_FILTER_SIZE,TIME_SERIES_FILTER_SIZE),sides=1))
			} else {
				pressure_history <- down_events$pressure
			}
			i <- i+1
		}
		current_time <- proc.time()['elapsed']
		event_time_delta_secs <- current_time - last_plot_time
		if (FALSE) { # (event_time_delta_secs > PLOT_DELAY_MSECS) {
			# PRESSURE
			if (TIME_SERIES_TIME_AXIS == TRUE) {
				matplot(x=down_events$time,y,typ='l',col=2:3,xlab='time',ylab='pressure',ylim=c(0,127))
			} else {
				matplot(pressure_history,typ='l',col=2:3,xlab='time',ylab='pressure',ylim=c(0,127))
			}
			boxplot(db$history$pressure,col='blue',border=NA,main='Key pressure',names.arg=1:128,axes=T,ylim=c(0,127))
			barplot(height=db$status$hit_count,col='blue',border=NA,main='Key press count',names.arg=1:128,axes=T,ylim=c(0,127))
			# DURATION
			if (up_count > 0) {
				dev.set(dev.next())
				barplot(db$history$duration,col='blue',border=NA,main='Key duration',names.arg=1:128,axes=T,ylim=c(0,127))
				barplot(height=key_total_duration,col='blue',border=NA,main='Key total duration',names.arg=1:128,axes=T)
				dev.set(dev.next())
			}
			last_plot_time <- current_time
		} else {
			cat(db$history$duration)
		}
	}
	close(c)
}

run()


